/**
 **************************************************************************************************************************
 * Class able to perform local profiling thanks to timer
 * Usage: create a profiler
 * Start starts profiling, Stop stops profiling
 * you can resume calling start again or reset the counter calling stop
 * You need to call stop before asking the duration of profiling
 * Profiling is not thread safe for now
 **************************************************************************************************************************
 * @file RBProfiler.h
 **************************************************************************************************************************/


#ifndef __RBPROFILER_H__
#define __RBPROFILER_H__

#ifdef  HEADER_ONCE
#pragma HEADER_ONCE
#endif

#ifdef  HEADER_MSG
#pragma HEADER_MSG(RBProfiler.h)
#endif


/**************************************************************************************************************************
 * Includes
 **************************************************************************************************************************/
#include "RBTimer.h"

/**************************************************************************************************************************
 * Forward declarations
 **************************************************************************************************************************/
#define RB_PROFILE(BlockName) \
    static RBProfiler* __g_kProfiler_##__LINE__ = new RBProfiler(BlockName); RBProfilerScoped __g_Scope_##__LINE__(__g_kProfiler_##__LINE__)

class RBProfiler;

/**************************************************************************************************************************
 * Classes
 **************************************************************************************************************************/
class RBProfilerManager : public RBSingleton<RBProfilerManager>
{
public:
            RBProfilerManager   ();
           ~RBProfilerManager   ();

    std::vector<RBProfiler*> Profilers;

};

class RBProfiler
{
public:
            RBProfiler  (const char* pcBlockName);
           ~RBProfiler  ();

    void    Start       ();
    void    Stop        ();
    void    Reset       ();

    uint32  GetDuration ();

    const char* GetBlockName();

private:
    RBTimer m_kTimer;
    uint32  m_uiTimeElapsed;
    bool    m_bStopped;
    const char* m_pcBlockName;
};

class RBProfilerScoped
{
public:
    RBProfilerScoped(RBProfiler* pProfiler) : m_pProfiler(pProfiler) { m_pProfiler->Start(); }
   ~RBProfilerScoped() { m_pProfiler->Stop(); }

private:
    RBProfiler* m_pProfiler;
};

/**************************************************************************************************************************/

#endif // __RBPROFILER_H__